# -*- coding: utf-8 -*-

from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext import db
import tweepy
import re
import time
from passwd import crc32hoge as p
#import sys

class Replied( db.Model ):
  id = db.IntegerProperty( required=True )

class Main:

  consumer_key        = p.consumer_key
  consumer_secret     = p.consumer_secret
  access_token        = p.access_token
  access_token_secret = p.access_token_secret

  table = [0] * 256

  def __init__( self ):
    self.auth = tweepy.OAuthHandler(self.consumer_key, self.consumer_secret)
    self.auth.set_access_token(self.access_token, self.access_token_secret)
    self.init_table( )

  def post( self ):
    api = tweepy.API(auth_handler=self.auth)
    id = 0
    since_id  = 0

    # order.( '-id' ) is just in case that
    #   two more Replied are registered due to something error.
    obj = Replied.all( ).order( '-id' ).get( )
    if obj:
      since_id = obj.id + 1

    results = api.mentions( since_id=since_id )
    results.reverse( )

    try:

      for m in results:
        # when api.update_status( ) invokes something error,
        #   the bot passes the tweet.
        # if you don't want to ignore it,
        #   you need to move this operation to after api.update_status( ).
        # and in generally, this 'if' statement is not necessary.
        #   just in case.
        if m.id > id:
          id = m.id
        if re.match( r'^@crc32hoge ', m.text ):
          buffer = '@' + m.user.screen_name + ' ' + \
                   str( hex( self.get_crc32( \
                   re.sub( r'^@crc32hoge ', '', m.text ) ) ) )[0:10]
          api.update_status( buffer, m.id )
          # just in case. to avoid heavy trafic.
          # and to be honest, this isn't necessary for last entry.
          time.sleep( 2.0 )

    # it's better to avoid to use 'Exception'.
    #   i recommend you to use something specific exception
    #   like 'Tweep Error'.
    except Exeption, e:
      raise e

    finally:

      if id > 0:
        if obj:
          obj.id = int(id)
        else:
          obj = Replied( id=int(id) )
        obj.put( )

  def init_table( self ):
    for i in xrange( 256 ):
      a = i
      for j in xrange( 8 ):
        old_a = a
        a >>= 1
        if old_a & 1:
          a ^= 0xedb88320
      self.table[i] = a
    return 

  def get_crc32( self, str ):
    a = 0xffffffff
    for s in str.encode( 'utf-8' ):
      a = a ^ ord( s ) & 0xffffffff
      a = ( a >> 8 ) ^ self.table[ a & 0xff ]
    return a ^ 0xffffffff

class MainHandler( webapp.RequestHandler ):

  def __init__( self ):
    self.application = Main( )

  def get( self ):
    self.application.post( )

def main( ):

  application = webapp.WSGIApplication( [ ( '/crc32hoge', MainHandler ) ], debug=True )

  util.run_wsgi_app( application )


if __name__ == '__main__':
  main( )

